package com.tom.demo.security;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tom.demo.common.response.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @Author: LanQiang
 * @Date: 2023/01/18/14:59
 * @Description: 认证过程中权限不足出现的异常 403
 */
@Component
@Slf4j
public class AccessDeniedHandlerImpl implements AccessDeniedHandler {

    @Resource
    private ObjectMapper objectMapper;

    /**
     * @description  返回权限不足的信息给前台
     * @param request
     * @param response
     * @param accessDeniedException
     * @author lanqiang
     * @date 2025/02/21 0001
     * 注意：只有通过配置类中配置接口权限，出现异常才会走这里的返回信息(.antMatchers("/user/pageList").hasAuthority("system:user:list"))
     * 如果使用注解来校验权限是否满足，那么抛出的异常不会到这里，会被我们的全局异常AccessDeniedException所拦截
     */
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)throws IOException {
        try {
            // 设置响应状态码和内容类型
            response.setStatus(403);
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            Result result = Result.error("禁止访问,权限不足,请联系管理员!", HttpStatus.FORBIDDEN.value(), null);
            String jsonValue = objectMapper.writeValueAsString(result);
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(jsonValue.getBytes(StandardCharsets.UTF_8));
            outputStream.flush();
            outputStream.close();
            log.error("AccessDeniedHandler<====>禁止访问,权限不足,请联系管理员!{}",accessDeniedException.getMessage());
        } catch (JsonProcessingException e) {
            log.error("AccessDeniedHandler<====>对象转json失败!{}",e.getMessage());
        }
    }
}